package com.gzhryc.shared_device.oem.code.profit.service;

import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.base.IProjectWalletService;
import com.gzhryc.shared_device.base.enums.WalletOperateEnum;
import com.gzhryc.shared_device.common.payment.dao.enums.ProjectWalletEnum;
import com.gzhryc.shared_device.oem.code.profit.dao.ProjectWalletDao;
import com.gzhryc.shared_device.oem.code.profit.dao.db.ProjectWallet;

import java.sql.SQLException;
import java.util.Date;

/**
 * 项目钱包相关操作
 *
 */
public class ProjectWalletService implements IProjectWalletService {

	static Logger log = Logger.getLogger(ProjectWalletService.class);

	public static ProjectWalletService self() {
		return MultiDBTools.getService(ProjectWalletService.class, true);
	}

	public static ProjectWalletService self(String jdbcKey) {
		return MultiDBTools.getService(jdbcKey, ProjectWalletService.class, true);
	}
	

	ProjectWalletDao dao;

	public ProjectWalletService(String jdbcKey) {
		this.dao = new ProjectWalletDao(jdbcKey);
	}

	public ProjectWallet getByKeys(Integer type, Long accountGroupId) {
		if (type != null && accountGroupId != null) {
			Conditions conditions = new Conditions(ProjectWallet.class);
			conditions.and().is("type", type);
			conditions.and().is("accountGroupId", accountGroupId);
			try {
				return dao.get(conditions);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	public Long sumMoneyByType(Integer type){
		if(type != null){
			Conditions conditions = new Conditions(ProjectWallet.class);
			conditions.and().is("type",type);

			try {
				return dao.sumMoneyByConditions(conditions);
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return 0L;
	}
	
	public Long sumMoney(){
		try {
			return dao.sumMoney();
		} catch (SQLException e) {
			log.error(e.getMessage(),e);
		}
		return 0L;
	}

	public synchronized boolean add(Long accountGroupId) {
		if(accountGroupId != null){
			JdbcSession.begin();
			try {
				boolean flag = true;
				for(ProjectWalletEnum.Type type : ProjectWalletEnum.Type.values()) {
					ProjectWallet wallet = new ProjectWallet();
					wallet.setType(type.index());
					wallet.setAccountGroupId(accountGroupId);
					wallet.setName(type.note());
					wallet.setMoney(0L);
					wallet.setDebtMoney(0L);
					wallet.setUpdateDate(new Date());
					if (dao.insert(wallet) <= 0) {
						flag = false;
						break;
					}
				}
				
				if(flag) {
					JdbcSession.commit();
					return true;
				}
				
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			} finally {
				JdbcSession.end();
			}
		}
		return false;
	}

	public synchronized ProjectWallet getOrAdd(Integer type, Long accountGroupId) {
		if(type != null && accountGroupId != null) {
			ProjectWallet wallet = getByKeys(type,accountGroupId);
			if(wallet == null) {
				wallet = new ProjectWallet();
				wallet.setType(type);
				wallet.setAccountGroupId(accountGroupId);
				wallet.setName(ProjectWalletEnum.Type.note(type));
				wallet.setMoney(0L);
				wallet.setDebtMoney(0L);
				wallet.setUpdateDate(new Date());
				try {
					if (dao.insert(wallet) > 0) {
						return wallet;
					}
				} catch (SQLException e) {
					log.error(e.getMessage(), e);
				}
			}else {
				return wallet;
			}
		}
		return null;
	}
	
 	public synchronized boolean reduceMoney(Integer type, Long accountGroupId, Long money, String operateNote) throws LogicException {
 		if(money <= 0) {
    		throw new LogicException("金额必须大于0");
    	}
		ProjectWallet wallet = getByKeys(type, accountGroupId);
		if (wallet == null) {
			log.error("项目钱包"+ProjectWalletEnum.Type.note(type)+"未启用");
			return false;
		}
		if (wallet.getMoney() > money) {
			Conditions condition = new Conditions(ProjectWallet.class);
			condition.and().is("type", type);
			condition.and().is("accountGroupId", accountGroupId);
			condition.and().is("money", wallet.getMoney());

			ProjectWallet walletUpdate = new ProjectWallet();
			walletUpdate.setMoney((wallet.getMoney() - money));
			try {
				if (dao.updateNotNull(walletUpdate, condition) > 0) {
					ProjectWalletOperateService.self().addOperateRecord(type, accountGroupId, WalletOperateEnum.Type.Reduce.index(), money, operateNote);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		} else {
			long debtMoney = money - wallet.getMoney();

			Conditions condition = new Conditions(ProjectWallet.class);
			condition.and().is("type", type);
			condition.and().is("accountGroupId", accountGroupId);
			condition.and().is("money", wallet.getMoney());
			condition.and().is("debtMoney", wallet.getDebtMoney());

			ProjectWallet walletUpdate = new ProjectWallet();
			walletUpdate.setMoney(0L);
			walletUpdate.setDebtMoney(wallet.getDebtMoney() + debtMoney);
			try {
				if (dao.updateNotNull(walletUpdate, condition) > 0) {
					ProjectWalletOperateService.self().addOperateRecord(type, accountGroupId, WalletOperateEnum.Type.Reduce.index(), money, operateNote);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return false;
	}

	public synchronized boolean addMoney(Integer type, Long accountGroupId, Long money, String operateNote) throws LogicException {
		if(money <= 0) {
    		throw new LogicException("金额必须大于0");
    	}
		ProjectWallet wallet = getByKeys(type, accountGroupId);
		if (wallet == null) {
			log.error("项目钱包"+ProjectWalletEnum.Type.note(type)+"未启用");
			return false;
		}
		if (wallet.getDebtMoney() > 0) {
			long newMoney = 0;
			long debtMoney = 0;
			if (wallet.getDebtMoney() > money) {
				debtMoney = wallet.getDebtMoney() - money;
			} else {
				newMoney = money - wallet.getDebtMoney();
			}

			Conditions condition = new Conditions(ProjectWallet.class);
			condition.and().is("type", type);
			condition.and().is("accountGroupId", accountGroupId);
			condition.and().is("money", wallet.getMoney());
			condition.and().is("debtMoney", wallet.getDebtMoney());

			ProjectWallet walletUpdate = new ProjectWallet();
			walletUpdate.setMoney((wallet.getMoney() + newMoney));
			walletUpdate.setDebtMoney(debtMoney);

			try {
				if (dao.updateNotNull(walletUpdate, condition) > 0) {
					ProjectWalletOperateService.self().addOperateRecord(type, accountGroupId, WalletOperateEnum.Type.Add.index(), money, operateNote);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		} else {
			Conditions condition = new Conditions(ProjectWallet.class);
			condition.and().is("type", type);
			condition.and().is("accountGroupId", accountGroupId);
			condition.and().is("money", wallet.getMoney());

			ProjectWallet walletUpdate = new ProjectWallet();
			walletUpdate.setMoney(wallet.getMoney() + money);
			try {
				if (dao.updateNotNull(walletUpdate, condition) > 0) {
					ProjectWalletOperateService.self().addOperateRecord(type, accountGroupId, WalletOperateEnum.Type.Add.index(), money, operateNote);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return false;
	}
}
